package com.lvy.hczn.front.business.common;

import io.swagger.annotations.ApiModelProperty;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class Constants {

    /******************WCS与WMS交互的MQTT主题**************************/
    /**
     * 称重topic
     */
    public static String TOPIC_MQTT_WEIGHT = "MQ3_Weight";

    /**
     * 分拣完成，货箱不入库
     * WMS反馈货箱是否继续入库
     * <p>
     * 分拣完成，货箱继续入库
     * WMS反馈货箱是否继续入库
     * <p>
     * 出库时
     */
    public static String TOPIC_MQTT_WMS_TO_WCS = "WMS_TO_WCS";

    /**
     * 响应WMS
     * 反馈称重结果
     * 响应不入库
     * 响应继续入库
     */
    public static String TOPIC_MQTT_WCS_TO_WMS = "WCS_TO_WMS";

    /**
     * 出库到位
     */
    public static String TOPIC_MQTT_MQ1_TO_WMS = "MQ1_TO_WMS";

    /**
     * WMS二次扫码
     * 获得货架编号+货箱编码
     * <p>
     * 响应入库/不入库
     * 如果货箱传感器丢失，触发扫码
     * 如果货箱未丢失，跳过扫码
     */
    public static String TOPIC_MQTT_MQ2_WMS_TO_WCS = "MQ2_WMS_TO_WCS";

    /**
     * 出库到位
     */
    public static String TOPIC_MQTT_MQ1__WCS_TO_WMS = "MQ1_WCS_TO_WMS";

    /**
     * wms发送给wcs的心跳检测新型号
     */
    public static String TOPIC_MQTT_WMS_WCS_WDSignal = "WD_WMS_TO_WCS";

    /**
     * wcs发送给wms的心跳检测信号
     */
    public static String TOPIC_MQTT_WCS_WMS_WDSignal = "WD_WCS_TO_WMS";

    /**
     * 请求分拣出库到位
     */
    public static String TOPIC_MQTT_MQ3_TO_WMS = "MQ3_TO_WMS";

    /**
     * 请求分拣称重请求
     */
    public static String TOPIC_MQTT_MQ3_WEIGHT_WMS = "MQ3_Weight_TO_WCS";

    /**
     * wms发送门禁指令
     */
    public static String TOPIC_MQTT_WMS_OPEN_DOOR = "WMS_OpenDoor";

    /**
     * Door01_IsOpen=false：门打开，true：门关闭
     */
    public static String TOPIC_MQTT_WMS_DOOR_IS_OPEN = "Door01_IsOpen";

    /**
     * 发送开门指令
     */
    public static String TOPIC_MQTT_WMS_OPEN_DOOR_ONE = "OpenDoor_01";

    /**
     * 新门禁响应WCS的topic
     */
    public static String TOPIC_MQTT_WMS_ACCESS_MANAGER_CODE_RESULT = "access_manager_code_result";

    /**
     * 响应成功ID
     */
    public static Integer ANSWER_ID_OK = 1;

    /**
     * 响应失败ID
     */
    public static Integer ANSWER_ID_ERROR = 2;

    /**
     * 备份成功，响应回wcs
     */
    public static String TOPIC_MQTT_BACKUP_TO_WCS = "Backup_TO_WCS";

    /**
     * wms发送恢复数据
     */
    public static String TOPIC_MQTT_RECOVER_TO_WCS = "Recover_TO_WCS";

    /**
     * wcs数据恢复topic
     */
    public static String TOPIC_MQTT_RECOVER_TO_WMS = "Recover_TO_WMS";


    /**
     * 入库完成WMS响应到wcs
     */
    public static String TOPIC_MQTT_STORAGE_OVER = "Storage_Over";

    /**
     * 入库离开缓存位响应wcs
     */
    public static String TOPIC_MQTT_LEAVE_BUFFER_POS_ANSWER = "LeaveBufferPos_Answer";

    /**
     * 请求分拣出库到位
     */
    public static String TOPIC_MQTT_MQ3_WCS_TO_WMS = "MQ3_WCS_TO_WMS";

    /**
     * 请求分拣出库到位WMS响应
     */
    public static String TOPIC_MQTT_MQ3_WMS_TO_WCS = "MQ3_WMS_TO_WCS";

    /**
     * 客户取货出库到位
     */
    public static String TOPIC_MQTT_MQ1_WCS_TO_WMS = "MQ1_WCS_TO_WMS";

    /**
     * 出库到位WMS响应
     */
    public static String TOPIC_MQTT_MQ1_WMS_TO_WCS = "MQ1_WMS_TO_WCS";

    /**
     * 同一个topic延时发送，plc以时间间隔扫描，每N毫秒一次性获取数据处理
     * 之后放数据字典，从redis读取
     * <p>
     * 注：原先wcs通过延时方式处理同一个topic发送频率，当前弄成同步方式，
     * 即：响应一个再发下一个，懒得去清除delay，暂时不确定wcs那边是否会
     * 沿用此方式，就先改成delay延时为1
     */
    public static Integer TOPIC_MQTT_SEND_DELAY = 300;

    /**
     * WCS按克计算，传入WCS的数值需乘以的系数
     */
    public static Integer WCS_WEIGHT_UNIT_COEFFICIENT = 1;

    /**
     * 货箱离开库位WMS响应
     */
    public static String TOPIC_MQTT_TAKE_BOX_ANSWER = "TakeBox_Answer";

    /**
     * 出库到位WMS响应
     */
    public static String TOPIC_MQTT_IN_BUFFER_POS_ANSWER = "InBufferPos_Answer";

    /**
     * 叠箱百分比
     */
    public static String TOPIC_MQTT_STACK_BOXES_PERCENT = "EmptySeat_TO_WCS";


    /********************************************/

    /******************根据state状态决定到wcs执行的操作**************************/

    /**
     * 底数
     */
    public static final int STATE_TO_WCS_BASE_NUMBER = 2;

    /**
     * 流程异常的数据
     */
    public static final int STATE_TO_WCS_ZERO = 0;

    /**
     * 发送出库指令
     */
    public static final int STATE_TO_WCS_ONE = 1;

    /**
     * wcs响应指令
     */
    public static final int STATE_TO_WCS_TWO = 2;

    /**
     * 货箱离开库位
     * 提前告诉WCS此箱可能会继续入库的货箱，（适用于所有，即，不带bit3，会持续下架，带bit3则只下一个箱子）
     */
    public static final int STATE_TO_WCS_THREE = 3;

    /**
     * 货箱离开库位响应
     */
    public static final int STATE_TO_WCS_FOUR = 4;

    /**
     * 出库到达缓存位
     */
    public static final int STATE_TO_WCS_FIVE = 5;

    /**
     * 出库到位wms响应
     */
    public static final int STATE_TO_WCS_SIX = 6;

    /**
     * 货箱不入库
     */
    public static final int STATE_TO_WCS_SEVEN = 7;

    /**
     * 货箱不入库响应
     */
    public static final int STATE_TO_WCS_EIGHT = 8;

    /**
     * 出库时货箱入库
     */
    public static final int STATE_TO_WCS_NINE = 9;

    /**
     * 出库时货箱入库响应
     */
    public static final int STATE_TO_WCS_TEN = 10;

    /**
     * 发送入库指令
     */
    public static final int STATE_TO_WCS_ELEVEN = 11;

    /**
     * 货箱入库响应
     */
    public static final int STATE_TO_WCS_TWELVE = 12;

    /**
     * 货箱入库完成
     */
    public static final int STATE_TO_WCS_THIRTEEN = 13;

    /**
     * 货箱入库完成响应
     */
    public static final int STATE_TO_WCS_FOURTEEN = 14;

    /**
     * 强制入库
     */
    public static final int STATE_TO_WCS_FIFTEEN = 15;

    /**
     * 强制入库响应
     */
    public static final int STATE_TO_WCS_SIXTEEN = 16;

    /**
     * 发送称重指令
     */
    public static final int STATE_TO_WCS_SEVENTEEN = 17;

    /**
     * 称重响应
     */
    public static final int STATE_TO_WCS_EIGHTEEN = 18;

    /**
     * 货箱毛重称重
     */
    public static final int STATE_TO_WCS_NINETEEN = 19;

    /**
     * 货箱毛重称重响应
     */
    public static final int STATE_TO_WCS_TWENTY = 20;

    public static final int STATE_TO_WCS_TWENTY_ONE = 21;

    public static final int STATE_TO_WCS_TWENTY_TWO = 22;

    public static final int STATE_TO_WCS_TWENTY_THREE = 23;

    public static final int STATE_TO_WCS_TWENTY_FOUR = 24;

    public static final int STATE_TO_WCS_TWENTY_FIVE = 25;

    public static final int STATE_TO_WCS_TWENTY_SIX = 26;

    public static final int STATE_TO_WCS_TWENTY_SEVEN = 27;

    public static final int STATE_TO_WCS_TWENTY_EIGHT = 28;

    public static final int STATE_TO_WCS_TWENTY_NINE = 29;

    public static final int STATE_TO_WCS_THIRTY = 30;

    public static final int STATE_TO_WCS_THIRTY_ONE = 31;

    public static final int STATE_TO_WCS_THIRTY_TWO = 32;

    /**
     * 货架备份数据
     */
    public static final int RECOVER_TYPE_ONE = 1;

    /**
     * 皮带备份数据
     */
    public static final int RECOVER_TYPE_TWO = 2;

    /**
     * 提升机备份数据
     */
    public static final int RECOVER_TYPE_THREE = 3;

    /**
     * 客户取货出库，即货箱/空箱出库且不入库
     */
    public static final int STATE_PROCESS_TYPE_ZERO = 0;

    /**
     * 分拣/生产出库到缓存位
     */
    public static final int STATE_PROCESS_TYPE_ONE = 1;

    /**
     * 称重
     */
    public static final int STATE_PROCESS_TYPE_TWO = 2;

    /**
     * 入库
     */
    public static final int STATE_PROCESS_TYPE_THREE = 3;

    /**
     * 强制入库
     */
    public static final int STATE_PROCESS_TYPE_FOUR = 4;

    /**
     * 货箱毛重称重
     */
    public static final int STATE_PROCESS_TYPE_FIVE = 5;

    /**
     * 分拣的订单箱入库
     */
    public static final int STATE_PROCESS_TYPE_SIX = 6;

    /**
     * 采购入库称重
     */
    public static final int STATE_PROCESS_TYPE_SEVEN = 7;


    /********************************************/

    /*******************返回web的code*************************/
    /**
     * 返回成功
     */
    public static final int SUCCESS = 0;

    /**
     * 返回失败
     */
    public static final int FAIL = 1;

    /**
     * 上架
     */
    public static String BOX_OPERATION_UP = "UP";

    /**
     * 下架
     */
    public static String BOX_OPERATION_DOWN = "DOWN";

    /**
     * 毛重称重
     */
    public static String BOX_OPERATION_WEIGHT = "WEIGHT";

    /**
     * WCS异常响应：缓存位反馈数据，消息队列无此货箱
     * */
    public static Integer ONE_ZERO_EIGHT=108;

    /********************************************/

    public static Map<Integer, Integer> map = new HashMap<>();

    /**
     * 流程校验，以及是否包含再流程中
     * 流程暂时定死，web流程传参，做个范围内的校验
     *
     * @param state
     * @return boolean
     * @author yw
     * @date 2022-03-23 13:31:53
     */
    public static boolean checkProcessState(Integer state) {
        if (map.isEmpty()) {
            map.put(STATE_TO_WCS_ZERO, STATE_TO_WCS_ZERO);
            map.put(STATE_TO_WCS_ONE, STATE_TO_WCS_ONE);
            map.put(STATE_TO_WCS_TWO, STATE_TO_WCS_TWO);
            map.put(STATE_TO_WCS_THREE, STATE_TO_WCS_THREE);
            map.put(STATE_TO_WCS_FOUR, STATE_TO_WCS_FOUR);
            map.put(STATE_TO_WCS_FIVE, STATE_TO_WCS_FIVE);
            map.put(STATE_TO_WCS_SIX, STATE_TO_WCS_SIX);
            map.put(STATE_TO_WCS_SEVEN, STATE_TO_WCS_SEVEN);
            map.put(STATE_TO_WCS_EIGHT, STATE_TO_WCS_EIGHT);
            map.put(STATE_TO_WCS_NINE, STATE_TO_WCS_NINE);
            map.put(STATE_TO_WCS_TEN, STATE_TO_WCS_TEN);
            map.put(STATE_TO_WCS_ELEVEN, STATE_TO_WCS_ELEVEN);
            map.put(STATE_TO_WCS_TWELVE, STATE_TO_WCS_TWELVE);
            map.put(STATE_TO_WCS_THIRTEEN, STATE_TO_WCS_THIRTEEN);
            map.put(STATE_TO_WCS_FOURTEEN, STATE_TO_WCS_FOURTEEN);
            map.put(STATE_TO_WCS_FIFTEEN, STATE_TO_WCS_FIFTEEN);
            map.put(STATE_TO_WCS_SIXTEEN, STATE_TO_WCS_SIXTEEN);
            map.put(STATE_TO_WCS_SEVENTEEN, STATE_TO_WCS_SEVENTEEN);
            map.put(STATE_TO_WCS_EIGHTEEN, STATE_TO_WCS_EIGHTEEN);
            map.put(STATE_TO_WCS_NINETEEN, STATE_TO_WCS_NINETEEN);
            map.put(STATE_TO_WCS_TWENTY, STATE_TO_WCS_TWENTY);
        }
        if (map.containsKey(state)) {
            return true;
        } else {
            return false;
        }
    }

    //wcs出库忙碌中检测（error_id:21-30）
    public static Map<Integer, Integer> wcsOutboundErrorMap = new HashMap<>();

    //wcs出库忙碌中检测（error_id:21-30）
    public static boolean checkOutboundErrorId(Integer state) {
        if (wcsOutboundErrorMap.isEmpty()) {
            wcsOutboundErrorMap.put(11, 11);
            wcsOutboundErrorMap.put(12, 12);
            wcsOutboundErrorMap.put(13, 13);
            wcsOutboundErrorMap.put(14, 14);
            wcsOutboundErrorMap.put(15, 15);
            wcsOutboundErrorMap.put(16, 16);
            wcsOutboundErrorMap.put(17, 17);
            wcsOutboundErrorMap.put(18, 18);
            wcsOutboundErrorMap.put(19, 19);
            wcsOutboundErrorMap.put(20, 20);
            wcsOutboundErrorMap.put(21, 21);
            wcsOutboundErrorMap.put(22, 22);
            wcsOutboundErrorMap.put(23, 23);
            wcsOutboundErrorMap.put(24, 24);
            wcsOutboundErrorMap.put(25, 25);
            wcsOutboundErrorMap.put(26, 26);
            wcsOutboundErrorMap.put(27, 27);
            wcsOutboundErrorMap.put(28, 28);
            wcsOutboundErrorMap.put(29, 29);
            wcsOutboundErrorMap.put(30, 30);
            wcsOutboundErrorMap.put(109, 109);
        }
        if (wcsOutboundErrorMap.containsKey(state)) {
            return true;
        } else {
            return false;
        }
    }

    //忽略的异常
    public static Map<Integer, Integer> wcsErrorMap = new HashMap<>();

    public static boolean checkErrorId(Integer state) {
        if (wcsErrorMap.isEmpty()) {
            wcsErrorMap.put(1, 1);
            wcsErrorMap.put(72, 72);
            wcsErrorMap.put(77, 77);
            wcsErrorMap.put(103, 103);
            wcsErrorMap.put(105, 105);
            wcsErrorMap.put(106, 106);
            wcsErrorMap.put(108, 108);
        }
        if (wcsErrorMap.containsKey(state)) {
            return true;
        } else {
            return false;
        }
    }

    /********************************************/

    /*******************mq*************************/
    public static String MQ_KEY_SUFFIX = "-front-wms";
    /********************************************/

    /*******************alarm_record报警记录*************************/
    /**
     * 类型:1:硬件报警
     */
    public static int ALARM_RECORD_ONE = 1;

    /**
     * 类型:2:wms,wcs交互流程报警
     */
    public static int ALARM_RECORD_TWO = 2;
    /********************************************/

    /*********************goodsBox***********************/

    /**
     * 货箱最小误差
     */
    //todo 先固定写在这，后期再处理
    public static BigDecimal GOODS_BOX_ERROR_MIN = BigDecimal.valueOf(200);

    /**
     * 货箱最大误差
     */
    //todo 先固定写在这，后期再处理
    public static BigDecimal GOODS_BOX_ERROR_MAX = BigDecimal.valueOf(200);

    /**
     * 货箱标准重量
     */
    //todo 先固定写在这，后期再处理
    public static BigDecimal GOODS_BOX_STANDARD_WEIGHT = BigDecimal.valueOf(3800);

    /**
     * 正在上架
     */
    public static String GOODS_BOX_STATE_ZERO = "0";

    /**
     * 正在下架
     */
    public static String GOODS_BOX_STATE_ONE = "1";

    /**
     * 已下架
     */
    public static String GOODS_BOX_STATE_TWO = "2";

    /**
     * 已上架
     */
    public static String GOODS_BOX_STATE_THREE = "3";

    /**
     * 异常货箱
     */
    public static String GOODS_BOX_STATE_FOUR = "4";

    /**
     * 已称重货箱
     */
    public static String GOODS_BOX_STATE_FIVE = "5";

    /**
     * 调拨在途
     */
    public static String GOODS_BOX_STATE_SIX = "6";

    /**
     * 货箱类型 0空箱
     */
    public static String GOODS_BOX_TYPE_ZERO = "0";

    /**
     * 货箱类型 1原料箱
     */
    public static String GOODS_BOX_TYPE_ONE = "1";

    /**
     * 货箱类型 2分拣原料入库
     */
    public static String GOODS_BOX_TYPE_TWO = "2";

    /**
     * 货箱类型 3分拣订单入库
     */
    public static String GOODS_BOX_TYPE_THREE = "3";

    /**
     * 货箱类型 4货箱入库
     */
    public static String GOODS_BOX_TYPE_FOUR = "4";

    /**
     * 货箱类型 5销售退货入库
     */
    public static String GOODS_BOX_TYPE_FIVE = "5";

    /**
     * 货箱类型 调拨配送入库
     */
    public static String GOODS_BOX_TYPE_SIX = "6";

    /**
     * 0、待出库
     */
    public static String OUTBOUND_DETAIL_STATUS_ZERO = "0";

    /**
     * 1、出库中
     */
    public static String OUTBOUND_DETAIL_STATUS_ONE = "1";

    /**
     * 2、已出库到位
     */
    public static String OUTBOUND_DETAIL_STATUS_TWO = "2";

    /**
     * 订单出库
     */
    public static int OUTBOUND_ORDER_TYPE_ONE = 1;

    /**
     * 退货出库
     */
    public static int OUTBOUND_ORDER_TYPE_TWO = 2;

    /**
     * 空箱出库
     */
    public static int OUTBOUND_ORDER_TYPE_THREE = 3;

    /**
     * 原料箱出库
     */
    public static int OUTBOUND_ORDER_TYPE_FOUR = 4;

    /**
     * 待入库/待出库
     */
    public static String ENTRY_ING = "0";

    /**
     * 已入库/已出库
     */
    public static String ENTRY_ED = "1";

    /**
     * 货箱缺失
     */
    public static String ENTRY_LOSS = "2";

    /**
     * 取货单取货中
     *
     */
    public static String DELIVERY_ORDER_STATUS_ZERO = "0";

    /**
     * 取货单入库中
     */
    public static String DELIVERY_ORDER_STATUS_ONE = "1";

    /**
     * 取货单已入库
     */
    public static String DELIVERY_ORDER_STATUS_TWO = "2";

    /**
     * 正常
     */
    public static int UP_OR_DOWN_POLICE_STATUS_ZERO = 0;

    /**
     * 异常
     */
    public static int UP_OR_DOWN_POLICE_STATUS_ONE = 1;



    /**
     * 待分拣
     */
    public static String SORT_TASK_DETAIL_WART = "0";


    /**
     * 正在分拣
     */
    public static String SORT_TASK_DETAIL_ING = "1";
    /**
     * 已分拣
     */
    public static String SORT_TASK_DETAIL_DONE = "2";

    /**
     * 已退货
     */
    public static String SORT_TASK_SORT_RETURNED = "3";

    /**
     * 分拣欠发
     */
    public static String SORT_TASK_SORT_OWE = "4";

    /**
     * 异常分拣
     */
    public static String SORT_TASK_SORT_ERROR = "5";


    /**
     * tms任务?
     */
    public static String SORT_TASK_TYPE_TMS = "1";

    /**
     * 紧急任务
     */
    public static String SORT_TASK_TYPE_URGENT = "2";

    /**
     * 普通订单任务
     */
    public static String SORT_TASK_TYPE_ORDER = "3";

    /**
     * 待分配
     */
    public static String SORT_TASK_STATUS_WAIT = "0";

    /**
     * 分拣中
     */
    public static String SORT_TASK_STATUS_ING = "1";

    /**
     * 已分拣
     */
    public static String SORT_TASK_STATUS_DONE = "2";

    /**
     * 自由平台
     */
    public static String SORT_TASK_SOURCE_OWN = "0";

    /**
     * 第三方
     */
    public static String SORT_TASK_SOURCE_OTHER = "1";

    /**
     * 有效，未删除
     */
    public static int DEL_FLAG_VALID = 0;

    /**
     * 无效，已删除
     */
    public static int DEL_FLAG_INVALID = 1;

    /**
     * 货箱最大体积
     */
    public static BigDecimal GOODS_BOX_MAX_VOLUME = new BigDecimal(1000);

    /**
     * 大货箱承受最大重量,单位：g
     */
    public static BigDecimal GOODS_BOX_MAX_WEIGHT = new BigDecimal(30000);

    /**
     * 货箱物品最小体积阙值，货箱合并或许需要
     */
    public static BigDecimal GOODS_BOX_MIN_VOLUME = new BigDecimal(100);

    /**
     * 小货箱承受最大重量,单位：g
     */
    public static BigDecimal GOODS_BOX_MIN_WEIGHT = new BigDecimal(15000);

    /**
     * 空箱
     */
    public static String GOODS_BOX_TYPE_EMPTY = "0";

    /**
     * 原料箱
     */
    public static String GOODS_BOX_TYPE_SPU = "1";

    /**
     * 订单箱
     */
    public static int GOODS_BOX_TYPE_ORDER = 2;

    /**
     * wcs errorId转码
     */
    public static int CONVERT_CODE_TYPE_ONE = 1;

    /**
     * wcs响应信息中间部分
     */
    public static String TYPE_WCS_RESPONSE = ":list:";

    /**
     * 货箱出库不入库,1、空箱；
     */
    public static int OUTBOUND_TYPE_ONE = 1;

    /**
     * 货箱出库不入库,2、非空箱出库且不入库；
     */
    public static int OUTBOUND_TYPE_TWO = 2;

    /**
     * 货箱前缀
     */
    public static String PREFIX_BOX = "LYG";

    /**
     * 货箱编码长度
     */
    public static int GOODS_BOX_LENGTH = 12;

    /**
     * 大货箱能容纳的体积（立方毫米）
     */
    public static int GOODS_BOX_VOLUME = 108376000;

    /**
     * 小货箱能容纳的体积（立方毫米）
     */
    public static int GOODS_BOX_VOLUME_SMALL = 54188000;

    /**
     * 分拣(降级/报损等)记录之降级
     */
    public static String SPU_SORT_RECORD_TYPE_ZERO = "0";

    /**
     * 分拣(降级/报损等)记录之报损
     */
    public static String SPU_SORT_RECORD_TYPE_ONE = "1";

    /**
     * 分拣称重异常
     */
    public static int WMS_SORT_WEIGHT_ERROR = 5000;

    /**
     * 采购入库称重异常
     */
    public static int WMS_PURCHASE_WEIGHT_ERROR = 5001;

    /**
     * 标品不超过的百分比，一份标品，不超过其一半，算是一份，如：一份标品1斤，货箱内，或者称重时的重量在1.5斤及以下，算是一份
     **/
    public static BigDecimal HALF_PERCENT = BigDecimal.valueOf(0.5);

    @ApiModelProperty("数据类型：1、销售分拣；2、调拨分拣；3、生产加工")
    public static Integer SORT_TASK_DATA_TYPE_ONE = 1;
    @ApiModelProperty("数据类型：1、销售分拣；2、调拨分拣；3、生产加工")
    public static Integer SORT_TASK_DATA_TYPE_TWO = 2;
    @ApiModelProperty("数据类型：1、销售分拣；2、调拨分拣；3、生产加工")
    public static Integer SORT_TASK_DATA_TYPE_THREE = 3;

    /********************************************/
}
